<?php
/**
 * Created by PhpStorm.
 * User: whwyy
 * Date: 2018/6/13 0013
 * Time: 14:17
 */

use BeReborn\Base\Authorize;
use BeReborn\Database\ActiveRecord;
use BeReborn\Event\Event;
use BeReborn\Event\IEvent;
use BeReborn\Exception\ComponentException;
use BeReborn\Http\HttpParams;
use BeReborn\Http\Request;
use BeReborn\Http\Response;
use BeReborn\Route\Router;
use BeReborn\Web\Application;

if (!function_exists('calc_hash_tbl')) {

	/**
	 * @param $u
	 * @param int $n | 表数量
	 * @param int $m
	 * @return int
	 */
	function calc_hash_tbl($u, $n = 20, $m = 10)
	{

		$h = sprintf("%u", crc32($u));

		$h1 = intval($h / $n);

		$h2 = $h1 % $n;

		$h3 = base_convert($h2, 10, $m);

		$h4 = sprintf("%02s", $h3);

		return $h4 == 0 ? '' : (int)$h4;

	}
}

if (!function_exists('merge')) {

	function merge($array1, $array2)
	{
		if (!is_array($array1)) {
			return $array2;
		} else if (!is_array($array2)) {
			return $array1;
		}
		foreach ($array2 as $key => $value) {
			$array1[$key] = $value;
		}
		return $array1;
	}
}

if (!function_exists('hash_datebase')) {

	/**
	 * @param $u
	 * @param int $s | 数据库数量
	 * @return int
	 */
	function hash_datebase($u, $s = 5)
	{
		$h = sprintf("%u", crc32($u));
		$h1 = intval(fmod($h, $s));
		return $h1 == 0 ? '' : $h1;
	}
}

if (!function_exists('get_unique_id')) {

	/**
	 * @param null $prefix
	 * @return int
	 */
	function get_unique_id($prefix = NULL)
	{
		$redis = BeReborn::$app->redis;
		$id = BeReborn::$app->id . ':' . ($prefix ?? 'uniqueID');
		if (!$redis->exists($id)) {
			$redis->set($id, 1);

			return 1;
		}
		$incr = $redis->incr($id);
		return $incr < 1 ? 1 : $incr;
	}
}

if (!function_exists('md5_uniqid')) {

	function md5_uniqid(string $prefix = null)
	{
		if (!$prefix) {
			return md5(uniqid(md5(microtime(true)), true));
		} else {
			return md5(uniqid($prefix . md5(microtime(true)), true));
		}
	}
}


if (!function_exists('request')) {

	/**
	 * @return Request
	 * @throws
	 */
	function request()
	{
		return BeReborn::$app->getRequest();
	}

}


if (!function_exists('Input')) {

	/**
	 * @return HttpParams
	 */
	function Input()
	{
		return request()->params;
	}

}


if (!function_exists('response')) {

	/**
	 * @return Response
	 * @throws
	 */
	function response()
	{
		if (!app()->has('response')) {
			return make('response', Response::class);
		}
		return app()->get('response');
	}

}

if (!function_exists('app')) {

	/**
	 * @return Application
	 */
	function app()
	{
		return BeReborn::$app;
	}

}


if (!function_exists('redirect')) {

	/**
	 * @param $url
	 * @return int
	 */
	function redirect($url)
	{
		return response()->redirect($url);
	}

}

if (!function_exists('redis')) {

	/**
	 * @return \Redis
	 * @throws
	 */
	function redis()
	{
		return BeReborn::$app->getRedis();
	}
}

if (!function_exists('router')) {

	/**
	 * @return Router
	 * @throws
	 */
	function router()
	{
		return BeReborn::$app->router;
	}
}


if (!function_exists('isInCircle')) {

	/**
	 * @param int $centerX1
	 * @param int $centerY1
	 * @param int $x2
	 * @param int $y2
	 * @param int $r
	 * @return bool
	 * 判断是否在中心点
	 */
	function isInCircle(int $centerX1, int $centerY1, int $x2, int $y2, $r = 100)
	{
		$distance = sqrt(($y2 - $centerY1) * ($y2 - $centerY1) + ($x2 - $centerX1) * ($x2 - $centerX1));
		if ($distance > $r) {
			return false;
		} else {
			return true;
		}
	}
}


if (!function_exists('env')) {

	/**
	 * @param $key
	 * @param null $default
	 * @return array|false|string|null
	 */
	function env($key, $default = null)
	{
		$env = getenv($key);
		if ($env === false) {
			return $default;
		}
		return $env;
	}

}


if (!function_exists('shutdown')) {

	/**
	 * @param $callback
	 * @param $param
	 */
	function shutdown($callback, $param)
	{
		register_shutdown_function($callback, $param);
	}

}


if (!function_exists('setCommand')) {

	/**
	 * @param bool $isCommand
	 * @return mixed
	 */
	function setCommand($isCommand = true)
	{
		return app()->isCommand = $isCommand;
	}

}
if (!function_exists('setTask')) {

	/**
	 * @param bool $isCommand
	 * @return mixed
	 */
	function setTask($isCommand = true)
	{
		return app()->isTask = $isCommand;
	}

}
if (!function_exists('getTask')) {

	/**
	 * @return bool
	 */
	function getTask()
	{
		return app()->isTask;
	}

}


if (!function_exists('getIsCommand')) {

	/**
	 * @return mixed
	 */
	function getIsCommand()
	{
		return app()->isCommand;
	}

}


if (!function_exists('getIsCli')) {

	/**
	 * @return mixed
	 */
	function getIsCli()
	{
		return app()->isCli;
	}

}


if (!function_exists('events')) {

	/**
	 * @return Event
	 * @throws ComponentException
	 */
	function events()
	{
		return app()->getEvent();
	}

}


if (!function_exists('on')) {

	/**
	 * @param $name
	 * @param $callback
	 * @param bool $isAppend
	 * @param bool $isRemove
	 * @throws Exception
	 */
	function on($name, $callback, $isAppend = false, $isRemove = false)
	{
		Event::on($name, $callback, $isAppend, $isRemove);
	}

}

if (!function_exists('storage')) {

	/**
	 * @param string $path
	 * @return string
	 * @throws Exception
	 */
	function storage($path = '')
	{
		return BeReborn::getRuntimePath($path);
	}

}


if (!function_exists('fire')) {

	/**
	 * @param $name
	 * @param array $param
	 * @param IEvent|null $callback
	 * @return bool|mixed
	 */
	function fire($name, array $param = [], IEvent $callback = null)
	{
		return Event::trigger($name, $param, $callback);
	}
}


if (!function_exists('of')) {

	/**
	 * @param $name
	 * @param IEvent|null $callback
	 * @return bool|mixed
	 */
	function of($name, IEvent $callback = null)
	{
		return Event::close($name, $callback);
	}
}

if (!function_exists('ofAll')) {

	/**
	 * @return bool|mixed
	 */
	function ofAll()
	{
		return Event::closeAll();
	}
}


if (!function_exists('exif_imagetype')) {

	/**
	 * @param $name
	 * @return string
	 */
	function exif_imagetype($name)
	{
		return get_file_extension($name);
	}
}

if (!function_exists('get_file_extension')) {

	function get_file_extension($filename)
	{
		$mime_types = array(
			'txt'  => 'text/plain',
			'htm'  => 'text/html',
			'html' => 'text/html',
			'php'  => 'text/html',
			'css'  => 'text/css',
			'js'   => 'application/javascript',
			'json' => 'application/json',
			'xml'  => 'application/xml',
			'swf'  => 'application/x-shockwave-flash',
			'flv'  => 'video/x-flv',

			// images
			'png'  => 'image/png',
			'jpeg' => 'image/jpeg',
			'gif'  => 'image/gif',
			'bmp'  => 'image/bmp',
			'ico'  => 'image/vnd.microsoft.icon',
			'tiff' => 'image/tiff',
			'svg'  => 'image/svg+xml',

			// archives
			'zip'  => 'application/zip',
			'rar'  => 'application/x-rar-compressed',
			'exe'  => 'application/x-msdownload',
			'msi'  => 'application/x-msdownload',
			'cab'  => 'application/vnd.ms-cab-compressed',

			// audio/video
			'mp3'  => 'audio/mpeg',
			'qt'   => 'video/quicktime',
			'mov'  => 'video/quicktime',

			// adobe
			'pdf'  => 'application/pdf',
			'psd'  => 'image/vnd.adobe.photoshop',
			'ai'   => 'application/postscript',
			'eps'  => 'application/postscript',
			'ps'   => 'application/postscript',

			// ms office
			'doc'  => 'application/msword',
			'rtf'  => 'application/rtf',
			'xls'  => 'application/vnd.ms-excel',
			'ppt'  => 'application/vnd.ms-powerpoint',

			// open office
			'odt'  => 'application/vnd.oasis.opendocument.text',
			'ods'  => 'application/vnd.oasis.opendocument.spreadsheet',
		);

		$explode = explode('.', $filename);
		$ext = strtolower(array_pop($explode));
		if (array_key_exists($ext, $mime_types)) {
			return $ext;
		} elseif (function_exists('finfo_open')) {
			$fInfo = finfo_open(FILEINFO_MIME);
			$mimeType = finfo_file($fInfo, $filename);
			finfo_close($fInfo);
			$mimeType = current(explode('; ', $mimeType));
			if (($search = array_search($mimeType, $mime_types)) == false) {
				return $mimeType;
			}
			return $search;
		} else {
			return 'application/octet-stream';
		}
	}
}


if (!function_exists('Auth')) {

	/**
	 * @return Authorize
	 */
	function Auth()
	{
		return BeReborn::getApp('auth');
	}

}


if (!function_exists('checkAuth')) {

	/**
	 * @return ActiveRecord|bool
	 * @throws Exception
	 */
	function checkAuth()
	{
		/** @var Authorize $auth */
		$auth = BeReborn::getApp('auth');
		return $auth::checkAuth();
	}
}

if (!function_exists('make')) {

	/**
	 * @param $className
	 * @param null $default
	 * @return mixed|object
	 * @throws ComponentException
	 * @throws Exception
	 */
	function make($className, $default = null)
	{
		if (BeReborn::$app->has($className)) {
			return BeReborn::$app->get($className);
		}

		return BeReborn::createObject($default);
	}

}

if (!function_exists('isXml')) {

	/**
	 * @param $body
	 * @return false|int
	 */
	function isXml($body)
	{
		return preg_match('/^<[a-zA-Z_]+>(.*?)?<\/[a-zA-Z_]+>$/', $body);
	}
}

if (!function_exists('toArray')) {

	/**
	 * @param $xml
	 * @return mixed
	 */
	function toArray($xml)
	{
		if (is_array($xml)) {
			return $xml;
		}
		if (!is_null($json = json_decode($xml, TRUE))) {
			return $json;
		}
		if (is_array($json)) {
			return $json;
		}
		if (!isXml($xml)) {
			return $xml;
		}
		$data = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
		if (is_array($data)) {
			return $data;
		}
		return json_decode(json_encode($data), TRUE);
	}

}


if (!function_exists('register_env_file')) {

	function register_env_file()
	{
		if (!file_exists(APP_PATH . '/.env')) {
			return;
		}
		$array = parse_ini_file(APP_PATH . '/.env', true);
		foreach ($array as $key => $val) {
			putenv($key . '=' . $val);
		}
	}

}


if (!function_exists('setComponents')) {

	/**
	 * @param $array
	 * @throws Exception
	 */
	function setComponents($array)
	{
		BeReborn::$app->setComponents($array);
	}
}
